local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M

local lib=require "ac.acctl_lib"

-- ip pool
M.ippool={}
-- allocated ip
M.ipalloc={}

function M.resip_init(pool)
	local ipstart = lib.ipstr_to_ip(pool.ipstart)
	local ipend = lib.ipstr_to_ip(pool.ipend)
	local mask = lib.ipstr_to_ip(pool.mask)
	mask = 2^32 - mask
	local s,e = ipstart % mask, ipend % mask
	if e < s then
		print("LUA: ipstart must less than ipend")
		os.exit()
	end

	-- skip 0 and 255
	ipstart = (s==0) and ipstart+1 or ipstart
	ipend = ((e+1)%mask == 0) and ipend-1 or ipend

	M.ippool.total = ipend-ipstart+1
	print(string.format("LUA: total ip: %d(%s~%s)", 
		M.ippool.total, pool.ipstart, pool.ipend))
	for i=ipstart, ipend do
		M.ippool[i] = "free"
	end
	M.ippool.res=pool
end

function M.resip_alloc(macstr)
	if aparr[macstr] == nil or 
		aparr[macstr].status == nil or
		aparr[macstr].status.network == nil then
		print("LUA: can not found:" .. macstr)
		return nil
	end

	if M.ippool.total <= 0 then
		print("LUA: have no more ip")
		return nil
	end

	local t = aparr[macstr].status.network
	local bak = lib.deepcopy(aparr[macstr].status.network)
	for k,v in pairs(t) do
		local preferip = 0;
		if M.ipalloc.macstr then
			preferip = M.ipalloc.macstr
		elseif v.ipaddr then
			preferip = lib.ipstr_to_ip(v.ipaddr)
			if M.ippool[preferip] == nil then
				preferip = table.maxn(M.ippool)
			end
		else
			preferip = table.maxn(M.ippool)
		end

		M.ippool[preferip] = nil 
		M.ipalloc.macstr = preferip 
		M.ippool.total = M.ippool.total - 1
		v.ipaddr = lib.ip_to_ipstr(preferip);
		v.gateway = M.ippool.res.gateway
		v.netmask = M.ippool.res.mask
		break
	end
	return bak,t
end

function M.resip_free(macstr)
	if M.ipalloc.macstr ~= nil then
		M.ippool[M.ipalloc.macstr] = "free"
		M.ipalloc.macstr = nil
	end
end
